#!/usr/bin/env python

import sys
from liwe.module import LiweModule

class Transaction ( LiweModule ):
	def __init__ ( self, liwe ):
		super ( Transaction, self ).__init__ ( liwe, "transaction" )

		self.dbm = self.liwe.dbm

	def get_hash ( self, custom ):
		import hashlib

		salt = self.cfg.get ( 'salt', '' )

		m = hashlib.md5 ()
		m.update ( custom )
		m.update ( salt )

		return m.hexdigest ()
		
	def paypal_cback ( self , kwargs = {} ):
		if kwargs.get ( 'payment_status' ) != 'Completed':
			sys.stderr.write ( 'TRANSACTION: payment not completed!\n' )
			# errore da gestire - mandare mail ?
			return


		custom, _hash = kwargs.get ( 'custom' ).split ( '#' )

		if not self.get_hash ( custom ) == _hash:
			sys.stderr.write ( 'TRANSACTION: failed hash check!\n' )
			# hash non corretto - forgery ?
			return

		custom = self.custom_parse_url ( custom )

		mods = "|".join ( custom.keys() )
		if not mods : mods = 'transaction' 

		values = { 'kind' : "PAYPAL",
			   'data' : str ( kwargs ),
			   'extra_data' : kwargs.get ( 'custom' ),
			   'module' : mods,	
			   'created' : '*NOW()'	 }
		self.dbm.insert ( 'transaction_track', values  )

		for module in custom.keys():
			m = custom [ module ]
			cback =  m.get ( 'cback' ) 
			if not cback : continue
			self.liwe.invoke ( cback , **m )
			
	#{{{TRANSACTION KIND
	def set_kind ( self, id_kind = 0, mode = '',name = '', descr = '', charge = 0, visible = 0 , module = '' ):
		values = { 'descr' : descr,
				   'charge' : charge,
				   'mode' : mode,
				   'name' : name,
				   'visible' : visible
				 }
		if module : values [ 'module' ] = module

		if not id_kind:
				values [ 'created' ] = '*NOW()'
				self.dbm.insert ( 'transaction_kind', values )
				id_kind = self.dbm.insert_id ()
		else:
				self.dbm.update ( "transaction_kind", values, "id_kind = %s" % id_kind )
		values [ 'id_kind' ] = id_kind
		return values

	def get_kind ( self, id_kind = 0 ):
		if not id_kind:
			self.liwe.set_error ( '1', 'id_kind value is not valid' )
			return [];
		return self.dbm.single_row ( 'transaction_kind' , '*', 'id_kind = %s' % id_kind, debug = self.debug() )

	def del_kind ( self, ids = "" ):
		ids = ids.split ( "|" )
		str_ids = " ,".join ( ids )
		self.dbm.delete ( "transaction_kind", "id_kind IN ( %s )" % str_ids )

	def set_kind_visible ( self, ids = "", visible = 0 ):

		ids = ids.split ( "|" )
		str_ids = " ,".join ( ids )

		self.dbm.update ( "transaction_kind", { 'visible': visible }, "id_kind IN ( %s )" % str_ids )

	def list_kind ( self, descr = '', visible = -1, module = '', quant = 10, start_point = 0, do_count = 0 ):

		conds = []
		
		if descr: conds.append ( "descr like '%%s%%'" % name )
		if module: conds.append ( "module = '%s'" % module )
		if visible <> -1: conds.append ( "visible = %s" % visible )			

		extras = ''
		tot_rows = self.dbm.count ( 'transaction_kind', 'id_kind', ' AND '.join ( conds ) )
		if do_count:
				extras = " LIMIT %s,%s" % ( start_point, quant )


		resp = self.dbm.all_rows ( 'transaction_kind', '*', ' AND '.join ( conds ), extras = extras )
		if not resp:
				resp = []
		return { "rows" : resp, "tot_rows" : tot_rows }

	def get_charge ( self, id_kind = 0, totale = 0 ):
		if not id_kind:
			self.liwe.set_error ( '1', 'id_kind value is not valid' )
			return [];
		kind = self.get_kind ( id_kind )
		
		#TODO: calcolo del costo in base al totale della merce
		return { 'charge' : kind [ 'charge' ] , 'name' : kind [ 'name' ] }


	#}}}

	def _custom_get_module ( self, module ):
		mkey = "trans-%s" % module
		data = self.liwe.session.data.get ( mkey, {} )
		self.liwe.session.data [ mkey ] = data

		return data

	def custom_add ( self, module, key, values, is_list =  False ):
		data = self._custom_get_module ( module )
		if is_list :
			data [ key ] = data.get ( key , [] )
			if values in data  [ key ] : return
			data [ key ].append  ( values )
		else :
			data [ key ] = values

		keys = self._custom_get_module ( "keys" )
		keys [ module ] = 1


	def custom_del ( self, module, key ):
		data = self._custom_get_module ( module )
		if key in data: del data [ key ]
		

	def custom_del_module ( self, module ):
		mkey = "trans-%s" % module
		if not mkey in self.liwe.session.data: return

		del self.liwe.session.data [ mkey ]
		#self.liwe.session.data [ 'trans-keys' ].remove ( module )
		del self.liwe.session.data [ 'trans-keys' ] [ module ]

	def custom_serialize ( self ):
		import json

		res = {}

		keys = self._custom_get_module ( "keys" )	
		for k in keys:
			res [ k ] = self._custom_get_module ( k )

		if not res : return None 			
		return json.dumps ( res )

	def custom_get_url ( self ):
		import base64, gzip

		js = self.custom_serialize ()
		if not js: return None
		return base64.b64encode ( gzip.zlib.compress ( js ) )

	def custom_parse_url ( self, txt ):
		import base64, gzip, json

		return json.loads ( gzip.zlib.decompress ( base64.b64decode ( txt ) ) )
		


	
